package com.ala4.oxcafe.boot.advice;

import com.ala4.oxcafe.common.utils.JSONUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdvice;

import java.io.IOException;
import java.lang.reflect.Type;
import java.util.List;

/**
 * 打印请求body参数的日志
 *
 * @author PING
 * @version 1.0
 * @date 2024/12/6 12:44
 */
@Slf4j
@Component
@ControllerAdvice
public class LogRequestBodyAdvice implements RequestBodyAdvice {

    /**
     * 是否文件上传
     *
     * @return
     */
    public static boolean isUpload(String contentType) {
        return MediaType.APPLICATION_OCTET_STREAM_VALUE.equals(contentType)
                || MediaType.MULTIPART_FORM_DATA_VALUE.equals(contentType)
                || MediaType.MULTIPART_MIXED_VALUE.equals(contentType)
                || MediaType.MULTIPART_RELATED_VALUE.equals(contentType);
    }

    @Override
    public boolean supports(@NonNull MethodParameter methodParameter, @NonNull Type type, @NonNull Class<? extends HttpMessageConverter<?>> aClass) {
        return true;
    }

    @Override
    @NonNull
    public HttpInputMessage beforeBodyRead(@NonNull HttpInputMessage httpInputMessage, @NonNull MethodParameter methodParameter, @NonNull Type type, @NonNull Class<? extends HttpMessageConverter<?>> aClass) throws IOException {
        return httpInputMessage;
    }

    @Override
    @NonNull
    public Object afterBodyRead(@NonNull Object body, @NonNull HttpInputMessage httpInputMessage, @NonNull MethodParameter methodParameter, @NonNull Type type, @NonNull Class<? extends HttpMessageConverter<?>> aClass) {
        try {
            HttpHeaders headers = httpInputMessage.getHeaders();
            List<String> contentTypeList = headers.get("Content-Type");
            if (!CollectionUtils.isEmpty(contentTypeList) && !isUpload(contentTypeList.get(0))) {
                log.info("Body      : {}", JSONUtil.toJsonStr(body));
            }
        } catch (Exception e) {
            log.error("日志请求打印异常，不影响业务，吞并异常", e);
        }
        return body;
    }

    @Override
    @NonNull
    public Object handleEmptyBody(@NonNull Object body, @NonNull HttpInputMessage httpInputMessage, @NonNull MethodParameter methodParameter, @NonNull Type type, @NonNull Class<? extends HttpMessageConverter<?>> aClass) {
        return body;
    }
}
